﻿#ifndef REGEXP_H_INCLUDED
#define REGEXP_H_INCLUDED

#include <regex>

namespace df{

	template<typename CharT>
	class RegexpResult{
	public:
		RegexpResult(std::basic_regex<CharT> & r, const CharT * start, const CharT * end)
			:rege(r)
			, iterStart(start)
			, iterEnd(end)
		{

		}

		RegexpResult(RegexpResult && r)
			:match_(std::move(r.match_))
			, rege(r.rege)
			, iterStart(r.iterStart)
			, iterEnd(r.iterEnd)
		{
		}

		class RegexpIter
		{
		public:
			RegexpIter(RegexpResult & r)
				:regRes(r)

			{
			}

			



			RegexpIter & operator++()
			{
				regRes.iterStart = regRes.match_[0].second;
				return *this;
			}

			std::match_results<const CharT *> & operator*()
			{
				return regRes.match_;
			}

			bool operator !=(RegexpIter)
			{
				return std::regex_search(regRes.iterStart, regRes.iterEnd, regRes.match_, regRes.rege);
			}

		private:
			RegexpResult & regRes;
		};

		////match[0]: 返回整个匹配序列
		String getFirst(){
			if (std::regex_search(iterStart, iterEnd, match_, rege))
				return match_[0].str();
			return tt_("");
		}


		//match[0]: 代表整个匹配序列 ；match[1]:代表第一个匹配子序列() ；match[2]: 代表第二个匹配子序列
		String get(intptr_t index){
			if (std::regex_search(iterStart, iterEnd, match_, rege)
				&& (intptr_t)match_.size() > index)
				return match_[index].str();
			return tt_("");
		}

		//获取一行匹配
		std::match_results<const CharT *>  getMatch()
		{
			std::regex_search(iterStart, iterEnd, match_, rege);
			return match_;
		}

		RegexpIter begin()
		{
			return RegexpIter(*this);
		}

		RegexpIter end()
		{
			return RegexpIter(*this);
		}

	private:
		std::match_results<const CharT *> match_;
		std::basic_regex<CharT> & rege;
		const CharT * iterStart;
		const CharT * iterEnd;


		DF_DISABLE_COPY_ASSIGN(RegexpResult);

	};

	template<typename CharT>
	class BaseRegexp
	{
	public:

		inline BaseRegexp()
		{
			
		}



		inline BaseRegexp(const BaseChar<CharT> & str)
			: regex_(str.begin(), str.Size(), std::regex_constants::ECMAScript)
		{
			static_assert(std::is_same<CharT, char>::value || std::is_same<CharT, wchar_t>::value
				, "Regexp template only accept char,wchar_t");
		}



		BaseRegexp(BaseRegexp && r)
			:regex_(std::move(r.regex_))
		{
		}

		inline void SetStr(const BaseChar<CharT> & str)
		{
			regex_.assign(str.begin(), str.Size(), std::regex_constants::ECMAScript);
		}

		inline void Assign(const BaseChar<CharT> & str)
		{
			SetStr(str);
		}



		inline bool IsMatch(const BaseChar<CharT> & str)
		{
			return std::regex_match(str.begin(), str.end(), regex_);
		}


		inline RegexpResult<CharT> Search(const BaseChar<CharT> & str)
		{
			return RegexpResult<CharT>(regex_, str.begin(), str.end());
		}


		////*******************************************
		//// Summary : 获取所有匹配结果
		//// Parameter - const std::basic_string<CharT> & str : 原字串
		//// Parameter - const LambdaT & func : void(resString res) 或bool(resString res)返回false中断遍历
		////*******************************************
		//template<class LambdaT>
		//inline int SearchAll(const std::basic_string<CharT> & str, const LambdaT & func)
		//{
		//	resString res;
		//	int count = 0;
		//	typename std::basic_string<CharT>::const_iterator it = str.begin();
		//	while (std::regex_search(it, str.end(), res.res_, regex_))
		//	{
		//		it = res.res_[0].second;
		//		count++;
		//		if (!df::ExecuteFunctor(func, res))
		//			return count;
		//		//func(res);
		//	}
		//	return count;
		//}




		//*******************************************
		// Summary : 正则替换所有匹配
		// Parameter - const std::basic_string<CharT> & sourceStr : 原字串
		// Parameter - const std::basic_string<CharT> & replaceStr : 子表达式占位符:$1 ... $n
		// Returns - std::basic_string<CharT> : 替换结果
		//*******************************************
		inline std::basic_string<CharT> ReplaceAll(const BaseChar<CharT> & sourceStr
			, const std::basic_string<CharT> & replaceStr)
		{
			std::basic_string<CharT> res;
			std::regex_replace(std::back_inserter(res), sourceStr.begin(), sourceStr.end()
				, regex_, replaceStr);
			return res;
		}

		///只替换首个匹配
		inline std::basic_string<CharT> Replace(const BaseChar<CharT> & sourceStr
			, const std::basic_string<CharT> & replaceStr)
		{
			std::basic_string<CharT> res;
			std::regex_replace(std::back_inserter(res), sourceStr.begin(), sourceStr.end(), regex_, replaceStr, std::regex_constants::format_first_only);
			return res;
		}



	private:
		std::basic_regex<CharT> regex_;

		BaseRegexp(const BaseRegexp& cp);
		BaseRegexp& operator = (const BaseRegexp& cp);
	};

	typedef  BaseRegexp<TCHAR> Regexp;
	typedef  BaseRegexp<char> RegexpA;
	typedef  BaseRegexp<wchar_t> RegexpW;



	//template<typename MatchT>
	//struct MatchTraits
	//{};

	//template<>
	//struct MatchTraits<const char *>
	//{
	//	typedef std::string sType;
	//	typedef char cType;
	//};
	//template<>
	//struct MatchTraits<const wchar_t *>
	//{
	//	typedef std::wstring sType;
	//	typedef wchar_t cType;
	//};
	//template<>
	//struct MatchTraits<typename std::string::const_iterator>
	//{
	//	typedef std::string sType;
	//	typedef char cType;
	//};
	//template<>
	//struct MatchTraits<typename std::wstring::const_iterator>
	//{
	//	typedef std::wstring sType;
	//	typedef wchar_t cType;
	//};

	//template<typename CharT>
	//class RegexpRes
	//{
	//public:
	//	RegexpRes()
	//	{}

	//	RegexpRes(RegexpRes && r)
	//		: res_(std::move(r.res_))
	//	{
	//	}

	//	template<class T>
	//	inline static auto SubMatchStr(const T & sub) -> decltype(sub.str())
	//	{
	//		return sub.str();
	//	}

	//	inline typename MatchTraits<CharT>::sType GetRes(size_t index)
	//	{
	//		if (res_.size() > index)
	//			return res_[index].str();
	//		return c_t(typename MatchTraits<CharT>::cType, "");
	//	}

	//	inline typename MatchTraits<CharT>::sType GetRes()
	//	{
	//		MY_ASSERT(res_.size() > 0);
	//		return res_[0].str();
	//	}
	//	//*******************************************
	//	// Summary : 获取指定下标子表达式结果字串
	//	// Parameter - const LambdaT & func : void(stringRef res)
	//	// Parameter - size_t index : 子表达式下标(从1开始),0表示第一个匹配结果
	//	// Returns - bool : 是否有此匹配
	//	//*******************************************
	//	template<class LambdaT>
	//	bool GetRes(const LambdaT & func, size_t index)
	//	{
	//		if (res_.size() > index)
	//		{
	//			func(res_[index].str());
	//			return true;
	//		}
	//		return false;
	//	}


	//	//*******************************************
	//	// Summary : 获取所有子表达式结果
	//	// Parameter - const LambdaT & func : void(stringRef res)
	//	// Parameter - size_t startIndex : 遍历起始下标
	//	//*******************************************
	//	template<class LambdaT>
	//	void GetEachRes(const LambdaT & func, size_t startIndex = 0)
	//	{
	//		for (size_t i = startIndex; i < res_.size(); i++)
	//		{
	//			func(res_[i].str());
	//		}
	//	}

	//	std::match_results<CharT> res_;
	//private:
	//	RegexpRes(const RegexpRes& cp);
	//	RegexpRes& operator = (const RegexpRes& cp);
	//};
}

#endif